﻿/**
 * 压缩帮助类
 * 
 * 单元检查人签名：cxs
 * 单元检查日期：2014-7-25
 */
using UnityEngine;
using System.Collections;
using ComponentAce.Compression.Libs.zlib;
using System.IO;
using System;

/// <summary>
/// 压缩帮助类
/// </summary>
public class ZlibHelper
{
    /// <summary>
    /// 对原始字节数组进行zlib压缩，得到处理结果字节数组
    /// </summary>
    /// <param name="OrgByte">需要被压缩的原始Byte数组数据</param>
    /// <param name="CompressRate">压缩率：默认为zlibConst.Z_DEFAULT_COMPRESSION</param>
    /// <returns>压缩后的字节数组，如果出错则返回null</returns>
    public static byte[] CompressBytesToBytes(byte[] OrgByte, int CompressRate = zlibConst.Z_DEFAULT_COMPRESSION)
    {
        if (OrgByte == null) return null;

        try
        {
            //-----------------------
            //step1: 对原始数进行压缩
            //-----------------------
            MemoryStream OrgStream = new MemoryStream(OrgByte);
            MemoryStream CompressedStream = new MemoryStream();
            ZOutputStream outZStream = new ZOutputStream(CompressedStream, CompressRate);
            CopyStream(OrgStream, outZStream);
            outZStream.finish();//重要！否则结果数据不完整！
            //程序执行到这里，CompressedStream就是压缩后的数据
            if (CompressedStream == null) return null;

            return CompressedStream.ToArray();
        }
        catch
        {
            return null;
        }
    }


    /// <summary>
    /// 对经过zlib压缩的数据，进行解密和zlib解压缩，得到原始字节数组
    /// </summary>
    /// <param name="CompressedBytes">被压缩的Byte数组数据</param>
    /// <returns>解压缩后的字节数组，如果出错则返回null</returns>
    public static byte[] DeCompressBytesToBytes(byte[] CompressedBytes)
    {
        if (CompressedBytes == null) return null;

        try
        {
            //-----------------------
            //解压缩
            //-----------------------
            MemoryStream CompressedStream = new MemoryStream(CompressedBytes);
            MemoryStream OrgStream = new MemoryStream();
            ZOutputStream outZStream = new ZOutputStream(OrgStream);
            CopyStream(CompressedStream, outZStream);
            outZStream.finish();//重要！
            //程序执行到这里，OrgStream就是解压缩后的数据


            if (OrgStream == null) return null;
            return OrgStream.ToArray();
        }
        catch (Exception ex)
        {
            Debug.LogException(ex);
            return null;
        }
    }


    /// <summary>
    /// 压缩字符串
    /// </summary>
    /// <param name="SourceString">需要被压缩的字符串</param>
    /// <returns>压缩后的字符串，如果失败则返回null</returns>
    public static string CompressString(string SourceString, int CompressRate = zlibConst.Z_DEFAULT_COMPRESSION)
    {
        byte[] byteSource = System.Text.Encoding.UTF8.GetBytes(SourceString);
        byte[] byteCompress = CompressBytesToBytes(byteSource, CompressRate);
        if (byteCompress != null)
        {
            return Convert.ToBase64String(byteCompress);
        }
        else
        {
            return null;
        }
    }
    /**/
    /// <summary>
    /// 解压字符串
    /// </summary>
    /// <param name="SourceString">需要被解压的字符串</param>
    /// <returns>解压后的字符串，如果处所则返回null</returns>
    public static string DecompressString(string SourceString)
    {
        byte[] byteSource = Convert.FromBase64String(SourceString);
        byte[] byteDecompress = DeCompressBytesToBytes(byteSource);
        if (byteDecompress != null)
        {
            return System.Text.Encoding.UTF8.GetString(byteDecompress);
        }
        else
        {
            return null;
        }
    }




    private static void CopyStream(System.IO.Stream input, System.IO.Stream output)
    {
        byte[] buffer = new byte[2000];
        int len;
        while ((len = input.Read(buffer, 0, 2000)) > 0)
        {
            output.Write(buffer, 0, len);
        }
        output.Flush();
    }

    /// <summary>
    /// 将解压缩过的二进制数据转换回字符串
    /// </summary>
    /// <param name="zipData"></param>
    /// <returns></returns>
    public static string GetStringByGZIPData(byte[] zipData)
    {
        return (string)(System.Text.Encoding.UTF8.GetString(zipData));
    }

    public static MemoryStream OrgStream { get; set; }
}
